<template>
  <div
    class="ui-search"
    :style="style"
    :class="['ui-search--' + size]"
  >
    <ui-textbox
      class="ui-search__input"
      ref="textbox"
      v-model.trim="keyword"
      :size="size"
      :readonly="loading"
      :placeholder="placeholder"
      @keyup.native.enter="handleNativeEnter"
      @input="handleInput"
      @blur="handleBlur"
    >
      <span v-if="loading" slot="suffix" class="ui-search__btn is-loading">
        <ui-icon name="loading"></ui-icon>
      </span>
      <span v-else-if="showClear" slot="suffix" class="ui-search__btn is-clear" @click="handleClear" title="清除搜索"></span>
      <span v-else slot="suffix" class="ui-search__btn is-search" title="点击搜索">
        <i class="el-icon-search"></i>
      </span>
    </ui-textbox>
  </div>
</template>
<script>
import UiTextbox from '../textbox'

export default {
  name: 'UiSearch',
  components: {
    UiTextbox
  },
  props: {
    width: {
      type: String
    },
    loading: {
      type: Boolean,
      default: false
    },
    value: {
      type: String
    },
    data: {
      type: Array,
      default: () => []
    },
    placeholder: {
      type: String
    },
    size: {
      type: String,
      default: 'small'
    },
    props: {
      type: Array,
      default: () => []
    },
    immediate: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      keyword: ''
    }
  },
  computed: {
    innerValue: {
      get() {
        return this.value
      },
      set(val) {
        this.$emit('input', val)
        this.handleSearch(val)
      }
    },
    style() {
      const sy = {}
      if (this.width) {
        sy.width = this.width
      }
      return sy
    },
    showClear() {
      return this.value === this.keyword && (this.value !== '' && this.keyword !== '')
    }
  },
  watch: {
    value: {
      immediate: true,
      handler(val) {
        this.keyword = val ? String(val).trim() : ''
      }
    },
    data() {
      this.search()
    }
  },
  methods: {
    handleSearch() {
      this.doSearch()
    },
    handleClear() {
      this.doSearch(() => {
        this.keyword = ''
      })
    },
    handleInput() {
      if (this.immediate) {
        this.doSearch()
      }
    },
    handleBlur() {
      // 避免失去焦点就触发搜索，但是还是需要保留重复点击搜索框能够触发搜索的逻辑
      if (this.value === this.keyword) {
        return
      }
      // blur时增加延时，优先清空和搜索图标点击的逻辑
      this._blurSearch = setTimeout(() => {
        this.doSearch()
      })
    },
    handleNativeEnter() {
      this.doSearch()
    },
    doSearch(callback) {
      if (this._disableSearch) {
        return
      }
      callback && callback()
      this.search()
      this._disableSearch = true
      this._searchTimer = setTimeout(() => {
        this._disableSearch = false
      }, 20)
    },
    search() {
      let result
      if (!this.keyword || !this.props || !this.props.length) {
        result = this.data
      } else if (Array.isArray(this.data)) {
        result = this.data.filter(v => {
          return this.props.some(p => String(v[p]).indexOf(this.keyword) >= 0)
        })
      }
      result = result || []
      this.$emit('input', this.keyword)
      this.$emit('search', {
        keyword: this.keyword,
        result
      })
    },
    focus() {
      this.$refs.textbox && this.$refs.textbox.focus()
    }
  },
  beforeDestroy() {
    clearTimeout(this._timer)
    clearTimeout(this._blurSearch)
    clearTimeout(this._searchTimer)
  }
}
</script>
<style lang="less">
.ui-search{
  width: 100%;
}
.ui-search__props{
  margin-right: 9px;
  .ui-button.el-button--text{
    color: #333;
  }
}
.ui-search__input.el-input{
  .el-input__suffix{
    right: 0;
  }
  .el-input-group__prepend{
    background-color: transparent;
  }
}
.ui-search__btn{
  display: inline-block;
  text-align: center;
  vertical-align: top;
  cursor: pointer;
  &.is-loading{
    height: 30px;
    width: 30px;
    line-height: 30px;
  }
  &.is-search{
    height: 30px;
    width: 30px;
    line-height: 30px;
    transition: color .3s cubic-bezier(.645,.045,.355,1);
    &:hover{
      color: #666;
    }
  }
  &.is-clear{
    width: 14px;
    height: 14px;
    border-radius: 50%;
    text-align: center;
    line-height: 14px;
    background-color: #ccc;
    color: #fff;
    margin-top: 8px;
    margin-right: 8px;
    position: relative;
    transform: rotate(45deg);
    &:after,&:before{
      content: '';
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      background-color: #fff;
    }
    &:after {
      width: 9px;
      height: 1px;
    }
    &:before {
      width: 1px;
      height: 9px;
    }
    &:hover{
      color: #fff;
      background-color: #999;
    }
  }
}
.ui-search--mini{
  .ui-search__btn{
    margin-right: -4px;
    &.is-loading{
      height: 28px;
      width: 28px;
      line-height: 28px;
    }
    &.is-search{
      height: 28px;
      width: 28px;
      line-height: 28px;
      font-size: 14px;
    }
    &.is-clear{
      margin-top: 7px;
      margin-right: 4px;
    }
  }
}
.ui-search--small {
  .ui-search__btn{
    margin-right: -3px;
    &.is-search{
      margin-top: 1px;
    }
    &.is-clear{
      margin-top: 9px;
      margin-right: 6px;
    }
  }
}
.ui-search--medium {
  .ui-search__btn{
    margin-right: -3px;
    &.is-search{
      margin-top: 3px;
    }
    &.is-clear{
      margin-top: 9px;
      margin-right: 6px;
    }
  }
}
</style>
